package com.neuron.trafikanten.search;

import java.io.IOException;
import java.util.ArrayList;

import org.apache.http.client.methods.HttpGet;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.app.SearchManager;
import android.content.Context;
import android.database.Cursor;
import android.database.MatrixCursor;
import android.net.Uri;
import android.provider.BaseColumns;
import android.util.Log;

import com.neuron.trafikanten.HelperFunctions;
import com.neuron.trafikanten.HelperFunctions.StreamWithTime;
import com.neuron.trafikanten.dataProviders.trafikanten.Trafikanten;
import com.neuron.trafikanten.dataProviders.trafikanten.TrafikantenSearch;
import com.neuron.trafikanten.dataSets.StationData;
import com.neuron.trafikanten.db.StationDbAdapter;

/*
 * This builds the autocomplete cursor shared by StationSearchProvider and AutocompleteCursorAdapter
 * NOTE : this is NOT threaded.
 */
public final class BuildAutocompleteCursor {
	private static final String TAG = "Trafikanten-BuildAutocompleteCursor";
	
	/*
	 * Autocomplete favorites and history
	 */
	private static void autoCompleteFavoritesHistory(MyMatrixCursor cursor, Context context, String selection, String query) {
		//TODO Performance : consider hanging on to database between autocomplete requests.
		StationDbAdapter stationDbAdapter = StationDbAdapter.getInstance(context);
		stationDbAdapter.autoComplete(cursor, selection, query);
		stationDbAdapter.close();
	}
	
	/*
	 * Autocomplete to web api.
	 */
	private static void autoCompleteWeb(MyMatrixCursor cursor, Context context, String selection, String query) {
		// Load data (in thread! content provider code deals with threading)
		try {
			String urlString = Trafikanten.getApiUrl() + "/Place/Autocomplete/" + HelperFunctions.properEncode(query);
			if (!selection.equals(StationSearchProvider.SEARCHTYPE_ROUTE)) {
				urlString = urlString + "?autocompleteType=" + selection;
			}
			Log.i(TAG,"Query url : " + urlString);
			final StreamWithTime streamWithTime = HelperFunctions.executeHttpRequest(context, new HttpGet(urlString), true);
			final JSONArray jsonArray = new JSONArray(HelperFunctions.InputStreamToString(streamWithTime.stream));
			final int arraySize = jsonArray.length();
			for (int i = 0; i < arraySize; i++) {
				final JSONObject json = jsonArray.getJSONObject(i);
				
				final int id = json.getInt("ID");
				final String name = json.getString("Name");
				final String extra = json.getString("District");
				final int type = json.getInt("Type");
				
				StationData station = new StationData(name, extra, id);
				TrafikantenSearch.searchForAddress(station);
				
				cursor.addRow(station.stationId, station.stopName, station.extra, type);
			}
		} catch (JSONException e) {
			Log.e(TAG,"Search failed, JSONException " + e.toString());
		} catch (IOException e) {
			Log.e(TAG,"Search failed, IOException " + e.toString());
		}
	}
	
	public static Cursor Autocomplete(Context context, String selection, String query) {
		// Setup content provider cursor for data:
		String[] columns = {
				BaseColumns._ID, 
			    SearchManager.SUGGEST_COLUMN_TEXT_1, 
			    SearchManager.SUGGEST_COLUMN_TEXT_2,
	            SearchManager.SUGGEST_COLUMN_ICON_1,			    
			    
	            SearchManager.SUGGEST_COLUMN_QUERY,
	            
	            SearchManager.SUGGEST_COLUMN_INTENT_ACTION,
	            SearchManager.SUGGEST_COLUMN_INTENT_DATA
			};
		final MyMatrixCursor cursor = new MyMatrixCursor(columns, selection);
		autoCompleteFavoritesHistory(cursor, context, selection, query);
		autoCompleteWeb(cursor, context, selection, query);
		return cursor;
	}
	
	public static class MyMatrixCursor extends MatrixCursor {
		private String mSelection;
		ArrayList<Integer> mStationIds = new ArrayList<Integer>();

		public MyMatrixCursor(String[] columnNames, String selection) {
			super(columnNames);
			mSelection = selection;
		} 
		
		public void addRow(int stationId, String stopName, String extra, int type) {
			// Check if we already have this station
			if (mStationIds.contains(stationId)) {
				return;
			}
			mStationIds.add(stationId);
			
			String id = Integer.toString(stationId);
			int icon = android.R.drawable.ic_menu_directions;
			switch(type) {
			case 1: // Reroute
				icon = android.R.drawable.ic_menu_revert;
				break;
			case 2: // POI
				icon = android.R.drawable.ic_menu_view;
				break;				
			case 3: // Address
				icon = android.R.drawable.ic_menu_mapmode;
				break;				
			}
			addRow(new String[] {id, stopName, extra, Integer.toString(icon), 
					stopName, 
					mSelection, "?name=" + Uri.encode(stopName) + "&extra=" + Uri.encode(extra) + "&id=" + id + "&type=" + type});

		}
		
	}

}
